package com.example.compiler;

import com.example.iannotation.Menu;
import com.google.auto.service.AutoService;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;


@AutoService(Processor.class)
public class CompilerApt extends AbstractProcessor {

    private Types mTypeUtils;
    private Messager mMessager;
    private Filer mFiler;
    private Elements mElementUtils;
//    private Map<String, FactoryGroupedClasses> factoryClasses = new LinkedHashMap<>();


    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mTypeUtils = processingEnvironment.getTypeUtils();
        mMessager = processingEnvironment.getMessager();
        mFiler = processingEnvironment.getFiler();
        mElementUtils = processingEnvironment.getElementUtils();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new LinkedHashSet<>();
        types.add(Menu.class.getCanonicalName());
        return types;
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
        List<String> aList = new ArrayList<>();
        List<MenuContainer> menus = new ArrayList<>();
        for (TypeElement typeElement : annotations) {
            Set<? extends Element> classElements = roundEnvironment.getElementsAnnotatedWith(typeElement);
            for (Element element : classElements) {
                if (element.getKind() == ElementKind.CLASS) {
                    TypeElement classElement = (TypeElement) element;
                    Menu menu = classElement.getAnnotation(Menu.class);
                    System.out.println(menu.name() + "|" + menu.functionId() + "|" + menu.needLogin());
                    aList.add(classElement.getQualifiedName().toString());
                    menus.add(new MenuContainer(menu, classElement.getQualifiedName().toString()));
                }
            }
        }


        aList.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("className:" + s);
            }
        });

        try {
            MenuCreator.createMenu(mFiler, menus);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return super.getSupportedSourceVersion();
    }
}